package controllers;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JOptionPane;
import javax.swing.filechooser.FileSystemView;

import views.Graphics;
import models.Board;
import models.Game;
import models.GameTimer;

public class Controller implements Observer
{
    private Game game;
    private Graphics view;

    public Controller(Game game)
    {
        this.game = game;
        game.addObserver(this);
        game.getTimer().addObserver(this);
    }

    public void initConfig()
    {
        view.configState();
    }

    public void initNewGame(int confg)
    {
        game.setConfig(confg);
        game.newGame();
        view.jugandoState();
    }

    public void pause()
    {
        game.pause();
        view.hideBoard();
        view.pausaState();
    }

    public void resume()
    {
        game.resume();
        view.showBoard();
        view.jugandoState();
    }

    public void stop()
    {
        game.stop();
        view.rendidoState();
    }

    public void setValueOnBoard(int row, int column, int value)
    {
        game.setNumberOnBoard(row, column, value);
    }

    public void verify()
    {
        if (game.verify())
        {
            game.pause();
            view.pressent("La solución es correcta");

            if (game.isTopScore())
            {
                String name = view.getBestTimeName();
                game.saveScore(name);
            }

            game.stop();
        }
        else
            view.pressent("La solución no es correcta, seguí intentandolo que el tiempo corre!");
    }

    //TODO: usar patron command
    //definir interfaz coommand con el metodo ejecutar y
    //las clases(comandos) UpdateTime UpdateMatrix UpdateNumber
    //todo en esta clase y crearlos en los observados(Game y Timer)
    // y pasarlos en el "arg1" luego en este metodo castear arg1 a
    //command y ejecutarlo.
    public void update(Observable arg0, Object arg1)
    {
        String who = (String)arg1;
        if (who.equals("Timer"))
            view.setTime(((GameTimer)arg0).getTime());
        else if (who.equals("Matrix"))
        {
            int[][] matrix = Board.getInstance().getMatrix();
            view.setMatrix(matrix);
            view.update();
        }
        else if (who.equals("Number"))
            view.updateNumber();
    }

    public void setView(Graphics view)
    {
        this.view = view;
    }

    public void meRindo()
    {
        game.meRindo();
        view.rendidoState();
    }

    public void vaciar()
    {
        game.vaciar();
    }

    public void globalHelp()
    {
        view.getHelp();
    }
    
    public void mostrarReglas()
    {
    	String reglas="";
		try {
			BufferedReader bufferedReader = new BufferedReader(new FileReader(FileSystemView.getFileSystemView().getHomeDirectory() +"/reglas.txt"));
			String line = "";
			while((line = bufferedReader.readLine())!=null){
	                         reglas+=line+"\n";
				}
			
			JOptionPane.showMessageDialog(null, reglas);
		} 
		catch (FileNotFoundException r) 
		{
			r.printStackTrace();
		} 
		catch (IOException f) {f.printStackTrace();
		}
    }

    //TODO: el controlador no deberia retornar valores
    public boolean help(int x, int y, int value)
    {
        int[][] solution = game.getLogic().getSolutionMatrix();

        return solution[x][y] == value;
    }

	public void top() {
		view.mostrarPuntajes(game.getTopTen());
		
	}
}
